home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 4 / Info_Mac IV CD-ROM (Pacific HiTech Inc.)(August 1994).iso / Development / Source / Halma 1.1.source Folder / Halma ƒ / Halma code ƒ / halma load-save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-21  |  6.4 KB  |  256 lines  |  [TEXT/KAHL]

  1. /**********************************************************************\
  2.  
  3. File:        halma load-save.c
  4.  
  5. Purpose:    This module handles loading and saving games on disk.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program in a file named "GNU General Public License".
  19. If not, write to the Free Software Foundation, 675 Mass Ave,
  20. Cambridge, MA 02139, USA.
  21.  
  22. \**********************************************************************/
  23.  
  24. #include "error.h"
  25. #include "halma load-save.h"
  26. #include "file interface.h"
  27. #include "halma.h"
  28. #include "dialogs.h"
  29. #include "environment.h"
  30. #include "util.h"
  31. #include "Script.h"
  32.  
  33. FSSpec            gameFile;
  34. Boolean            deleteTheThing;
  35.  
  36. typedef struct
  37. {
  38.     unsigned short    version;            /* for forward compatibility */
  39.     short            numRows;            /* number of rows in saved board */
  40.     short            numColumns;            /* number of columns in saved board */
  41.     short            theboard[9][9];        /* actual board */
  42.     short            numMoves;            /* number of moves so far */
  43.     short            numJumps;            /* number of jumps in current move so far */
  44.     short            stickyButtonRow;    /* which piece is down (row) */
  45.     short            stickyButtonColumn;    /* which piece is down (column) */
  46.     short            thisStartRow;        /* start of current jump chain (row) */
  47.     short            thisStartColumn;    /* start of current jump chain (column) */
  48.     Str255            thisJumpString;        /* current jump chain */
  49.     unsigned long    fullJumpPtrSize;    /* GetHandleSize(gTheFullJumpHandle) */
  50.     unsigned short    crc;                /* checksum */
  51. } SaveStruct;
  52.  
  53. void InitLoadSave(void)
  54. {
  55.     gameFile.name[0]=0x00;
  56.     deleteTheThing=FALSE;
  57. }
  58.  
  59. void LoadSaveDispatch(Boolean isLoad, Boolean useOldGame)
  60. {
  61.     if (isLoad)
  62.     {
  63.         if (GetSourceFile(&gameFile, FALSE, FALSE))
  64.             HandleError(GetSavedGame(&gameFile), FALSE);
  65.     }
  66.     else
  67.     {
  68.         useOldGame=useOldGame&&(gameFile.name[0]!=0x00);
  69.         if (useOldGame ? TRUE : GetDestFile(&gameFile, &deleteTheThing, "\pSave Halma game as..."))
  70.             HandleError(SaveGame(gameFile), FALSE);
  71.     }
  72. }
  73.  
  74. enum ErrorTypes SaveGame(FSSpec gameFile)
  75. {
  76.     OSErr            theError;
  77.     short            thisFile;
  78.     long            count;
  79.     SaveStruct        data;
  80.     short            i,j;
  81.     
  82.     data.numRows=gNumRows;
  83.     data.numColumns=gNumColumns;
  84.     for (i=0; i<9; i++)
  85.         for (j=0; j<9; j++)
  86.             data.theboard[i][j]=Board[i][j];
  87.     data.numMoves=gNumMoves;
  88.     data.numJumps=gNumJumps;
  89.     data.stickyButtonRow=gStickyButtonRow;
  90.     data.stickyButtonColumn=gStickyButtonColumn;
  91.     data.thisStartRow=gThisStartRow;
  92.     data.thisStartColumn=gThisStartColumn;
  93.     Mymemcpy((Ptr)data.thisJumpString, (Ptr)gThisJumpString, 256);
  94.     data.fullJumpPtrSize=GetHandleSize((Handle)gTheFullJumpHandle);
  95.     data.version=SAVE_VERSION;
  96.     data.crc=0;
  97.     data.crc=TheChecksum((Ptr)(&data), sizeof(SaveStruct));
  98.     
  99.     if (deleteTheThing)
  100.     {
  101.         if (gHasFSSpecs)
  102.             FSpDelete(&gameFile);
  103.         else
  104.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  105.     }
  106.     FlushVol(0L, gameFile.vRefNum);
  107.     
  108.     if (gHasFSSpecs)
  109.         theError=FSpCreate(&gameFile, CREATOR, SAVE_TYPE, smSystemScript);
  110.     else
  111.         theError=HCreate(gameFile.vRefNum, gameFile.parID,
  112.                         gameFile.name, CREATOR, SAVE_TYPE);
  113.     FlushVol(0L, gameFile.vRefNum);
  114.     
  115.     if (theError!=noErr)
  116.         return kCantCreateGame;
  117.     
  118.     if (gHasFSSpecs)
  119.         theError=FSpOpenDF(&gameFile, fsRdWrPerm, &thisFile);
  120.     else
  121.         theError=HOpen(gameFile.vRefNum, gameFile.parID,
  122.                         gameFile.name, fsRdWrPerm, &thisFile);
  123.     
  124.     if (theError!=noErr)
  125.         return kCantOpenGameToSave;
  126.  
  127.     count=sizeof(SaveStruct);
  128.     SetEOF(thisFile, count+data.fullJumpPtrSize);
  129.     SetFPos(thisFile, 1, 0L);
  130.     theError=FSWrite(thisFile, &count, &data);
  131.     
  132.     if (theError==noErr)
  133.     {
  134.         count=data.fullJumpPtrSize;
  135.         HLock((Handle)gTheFullJumpHandle);
  136.         theError=FSWrite(thisFile, &count, *gTheFullJumpHandle);
  137.         HUnlock((Handle)gTheFullJumpHandle);
  138.     }
  139.     
  140.     FSClose(thisFile);
  141.     FlushVol(0L, gameFile.vRefNum);
  142.  
  143.     if (theError!=noErr)
  144.     {
  145.         if (gHasFSSpecs)
  146.             FSpDelete(&gameFile);
  147.         else
  148.             HDelete(gameFile.vRefNum, gameFile.parID, gameFile.name);
  149.         
  150.         gameFile.name[0]=0x00;
  151.         return kCantWriteGame;
  152.     }
  153.     else deleteTheThing=TRUE;
  154.     
  155.     return allsWell;
  156. }
  157.  
  158. enum ErrorTypes GetSavedGame(FSSpec *gameFile)
  159. {
  160.     short            thisFile;
  161.     long            count;
  162.     short            i,j;
  163.     SaveStruct        data;
  164.     OSErr            theError;
  165.     unsigned short    checksum, savedChecksum;
  166.     Ptr                temp;
  167.     
  168.     if (gHasFSSpecs)
  169.         theError=FSpOpenDF(gameFile, fsRdPerm, &thisFile);
  170.     else
  171.         theError=HOpen(gameFile->vRefNum, gameFile->parID, gameFile->name, fsRdPerm, &thisFile);
  172.     
  173.     if (theError!=noErr)
  174.         return kCantOpenGameToLoad;
  175.     
  176.     count=sizeof(SaveStruct);
  177.     SetFPos(thisFile, 1, 0L);
  178.     theError=FSRead(thisFile, &count, &data);
  179.  
  180.     if (theError!=noErr)
  181.     {
  182.         FSClose(thisFile);
  183.         return kCantLoadGame;
  184.     }
  185.     
  186.     deleteTheThing=TRUE;
  187.     
  188.     if (data.version!=SAVE_VERSION)
  189.     {
  190.         FSClose(thisFile);
  191.         return kSaveVersionNotSupported;
  192.     }
  193.     
  194.     savedChecksum=data.crc;
  195.     data.crc=0;
  196.     checksum=TheChecksum((Ptr)(&data), sizeof(SaveStruct));
  197.     if (checksum!=savedChecksum)
  198.     {
  199.         gameFile->name[0]=0x00;
  200.         FSClose(thisFile);
  201.         return kBadChecksum;
  202.     }
  203.     
  204.     count=data.fullJumpPtrSize;
  205.     temp=NewPtr(count);
  206.     theError=FSRead(thisFile, &count, temp);
  207.     FSClose(thisFile);
  208.     
  209.     if (theError!=noErr)
  210.     {
  211.         DisposePtr(temp);
  212.         return kCantLoadGame;
  213.     }
  214.     
  215.     gNumRows=data.numRows;
  216.     gNumColumns=data.numColumns;
  217.     for (i=0; i<9; i++)
  218.         for (j=0; j<9; j++)
  219.             Board[i][j]=data.theboard[i][j];
  220.     gNumMoves=data.numMoves;
  221.     gNumJumps=data.numJumps;
  222.     gStickyButtonRow=data.stickyButtonRow;
  223.     gStickyButtonColumn=data.stickyButtonColumn;
  224.     gThisStartRow=data.thisStartRow;
  225.     gThisStartColumn=data.thisStartColumn;
  226.     Mymemcpy((Ptr)gThisJumpString, (Ptr)(data.thisJumpString), 256);
  227.     SetHandleSize((Handle)gTheFullJumpHandle, data.fullJumpPtrSize);
  228.     HLock((Handle)gTheFullJumpHandle);
  229.     Mymemcpy((Ptr)(*gTheFullJumpHandle), (Ptr)temp, data.fullJumpPtrSize);
  230.     HUnlock((Handle)gTheFullJumpHandle);
  231.     DisposePtr(temp);
  232.     
  233.     StartGame();
  234.     
  235.     return allsWell;
  236. }
  237.  
  238. unsigned short TheChecksum(Ptr input, unsigned short len)
  239. {
  240.     unsigned short    i;
  241.     Boolean            shiftedOut;
  242.     unsigned short    checksum;
  243.     
  244.     checksum=0;
  245.     for (i=0; i<len; i++)
  246.     {
  247.         shiftedOut=checksum&0x8000;
  248.         checksum+=*((unsigned char*)((long)input+i));
  249.         checksum<<=1;
  250.         if (shiftedOut)
  251.             checksum^=0xdead;
  252.     }
  253.     
  254.     return checksum;
  255. }
  256.